package rsp

import (
	"crypto/md5"
	"crypto/tls"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io"
	"math/rand"
	"net/http"
	"net/url"
	"proxy_resource_test/bootstrap/models"
	"strings"
	"time"
)

type TaskRspGather struct {
	ProxyAddr   string
	User        string
	Password    string
	UserTpl     string
	TargetStr   string
	OperateName string
}

var defaultTransport = &http.Transport{
	Proxy:               nil,
	TLSHandshakeTimeout: 20 * time.Second,
	MaxIdleConns:        100,
	MaxConnsPerHost:     100,
	IdleConnTimeout:     90 * time.Second,
	TLSClientConfig:     &tls.Config{InsecureSkipVerify: true},
}

func (t *TaskRspGather) newHTTPClient(proxyAddr, user, pass, userTpl string) *http.Client {
	u := fmt.Sprintf(userTpl, proxyAddr)
	proxyURL, err := url.Parse(u)
	if err != nil {
		fmt.Println(fmt.Errorf("解析代理失败: %v", err))
	}
	proxyURL.User = url.UserPassword(user, pass)
	transport := defaultTransport.Clone()
	transport.Proxy = http.ProxyURL(proxyURL)
	return &http.Client{
		Transport: transport,
		Timeout:   20 * time.Second,
	}
}

// PerformRequest 执行请求
// 2025 新增需求，兼容多个参数，使用宏替换
func (t *TaskRspGather) PerformRequest(country string) (error, float64, models.IpInfo) {
	var info models.IpInfo
	var state = 1
	// 例如：data_crawler-zone-ytb2296609-session-%s-sessTime-%d:password
	replacements := map[string]func() string{
		"<session>": func() string { return getSonyflake() },
		"<region>":  func() string { return country },
		"<st>":      func() string { return "5" },
	}
	for placeholder, getValue := range replacements {
		if idx := strings.Index(t.User, placeholder); idx != -1 {
			t.User = strings.Replace(t.User, placeholder, getValue(), 1)
		}
	}
	userAndPass := strings.Split(t.User, ":")
	if len(userAndPass) != 2 {
		return fmt.Errorf("用户名密码错误"), 0, info
	}
	client := t.newHTTPClient(t.ProxyAddr, userAndPass[0], userAndPass[1], t.UserTpl)
	//client := t.newHTTPClient(t.ProxyAddr, "ceshishifuqi-zone-custom-region-us", "ceshishifuqi", t.UserTpl)
	startTime := time.Now()
	req, _ := http.NewRequest("GET", t.TargetStr, nil)
	resp, err := client.Do(req)
	if err != nil {
		return err, 0, info
	}
	// 执行秒数
	timeSeconds := time.Since(startTime).Seconds()
	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		state = 2
		return fmt.Errorf("读取响应失败:%w", err), timeSeconds, info
	}
	parserFn, exists := Parsers[t.OperateName]
	if !exists {
		// 默认直接解到 IpInfo
		parserFn = func(body []byte) (models.IpInfo, error) {
			if err := json.Unmarshal(body, &info); err != nil {
				return models.IpInfo{}, fmt.Errorf("IpInfo 解析失败: %w", err)
			}
			return info, nil
		}
	}

	info, parseErr := parserFn(body)
	if parseErr != nil {
		return parseErr, timeSeconds, info
	}
	//if country != bd.Country {
	//	logging.Info("国家不一致", userAndPass[0], country, bd.Country)
	//}
	info.State = int64(state)
	return nil, timeSeconds, info
}

type CloudflareTrace struct {
	FL          string `json:"fl"`
	H           string `json:"h"`
	IP          string `json:"ip"`
	TS          string `json:"ts"`
	VisitScheme string `json:"visit_scheme"`
	UAG         string `json:"uag"`
	Colo        string `json:"colo"`
	Sliver      string `json:"sliver"`
	HTTP        string `json:"http"`
	Loc         string `json:"loc"`
	TLS         string `json:"tls"`
	SNI         string `json:"sni"`
	Warp        string `json:"warp"`
	Gateway     string `json:"gateway"`
	RBI         string `json:"rbi"`
	KEX         string `json:"kex"`
}

// 生成指定长度的随机字符串
func generateRandomString(length int) (string, error) {
	bytes := make([]byte, length)
	if _, err := rand.Read(bytes); err != nil {
		return "", err
	}

	// 将随机字节转换为可打印的 Base64 编码
	return hex.EncodeToString(bytes)[:length], nil
}

// 生成随机字符串+时间戳的哈希值
func getSonyflake() string {
	// 1. 生成随机字符串
	randomLength := 15
	randomStr, err := generateRandomString(randomLength)
	if err != nil {
		return ""
	}

	// 2. 获取当前时间戳（毫秒级）
	timestamp := time.Now().UnixNano() / int64(time.Millisecond)

	// 3. 组合随机字符串和时间戳
	dataToHash := fmt.Sprintf("%s%d", randomStr, timestamp)

	// 4. 计算 SHA-256 哈希
	hash := md5.Sum([]byte(dataToHash))

	// 5. 返回哈希值的十六进制表示
	return hex.EncodeToString(hash[:])
}

func getPopular() {
	var counter = []string{"AU", "CA", "CH", "FR", "GB", "HK", "IT", "JP", "KR", "MN", "MX", "MY", "NL", "PL", "RU", "SG", "TW", "US", "VN"}
	fmt.Println(counter)
}
